﻿@model IEnumerable<DevExtreme.NETCore.Demos.Models.Appointment>

@(Html.DevExtreme().Scheduler()
    .ID("scheduler")
    .DataSource(Model)
    .TextExpr("Text")
    .StartDateExpr("StartDate")
    .EndDateExpr("EndDate")
    .Views(new[] { SchedulerViewType.WorkWeek, SchedulerViewType.Month })
    .CurrentView(SchedulerViewType.WorkWeek)
    .CurrentDate(new DateTime(2017, 5, 25))
    .FirstDayOfWeek(FirstDayOfWeek.Sunday)
    .StartDayHour(9)
    .EndDayHour(19)
    .ShowAllDayPanel(false)
    .Height(600)
    .DataCellTemplate(new JS("dataCellTemplate"))
    .DateCellTemplate(new JS("dateCellTemplate"))
    .TimeCellTemplate(new JS("timeCellTemplate"))
    .OnAppointmentFormOpening("function(e) { onAppointmentFormOpening(e); }")
    .OnAppointmentAdding("function(e) { onAppointmentAdding(e); }")
    .OnAppointmentUpdating("function(e) { onAppointmentUpdating(e); }")
)

<script>
    var dinnerTime = { from: 12, to: 13 };
    var holidays = [
        new Date(2017, 4, 25),
        new Date(2017, 6, 4)
    ];

    function dataCellTemplate(itemData, itemIndex, itemElement) {
        var date = itemData.startDate;
        var isDisabled = isHoliday(date) || isWeekend(date);
        var element = $(`<div>${itemData.text}</div>`);

        if (isDisabled) {
            element.addClass('disable-date');
        } else if (isDinner(date)) {
            element.addClass('dinner');
        }

        return itemElement.append(element);
    }

    function dateCellTemplate(itemData, itemIndex, itemElement) {
        var element = $(`<div>${itemData.text}</div>`);

        if (isWeekend(itemData.date)) {
            element.addClass('disable-date');
        }

        return itemElement.append(element);
    }

    function timeCellTemplate(itemData, itemIndex, itemElement) {
        var element = $(`<div>${itemData.text}</div>`);

        if (isDinner(itemData.date)) {
            element
                .addClass('dinner')
                .append('<div class="cafe" />');
        }

        return itemElement.append(element);
    }

    function onAppointmentFormOpening(e) {
        debugger;
        var startDate = new Date(e.appointmentData.StartDate);
        if(!isValidAppointmentDate(startDate)) {
            e.cancel = true;
            notifyDisableDate();
        }
        applyDisableDatesToDateEditors(e.form);
    }

    function onAppointmentAdding(e) {
        if(!isValidAppointment(e.component, e.appointmentData)) {
            e.cancel = true;
            notifyDisableDate();
        }
    }

    function onAppointmentUpdating(e) {
        if(!isValidAppointment(e.component, e.newData)) {
            e.cancel = true;
            notifyDisableDate();
        }
    }

    function notifyDisableDate() {
        DevExpress.ui.notify("This date is disabled", "warning", 500);
    }

    function isValidAppointment(component, appointmentData) {
        var startDate = new Date(appointmentData.StartDate);
        var endDate = new Date(appointmentData.EndDate);
        var cellDuration = component.option('cellDuration');
        return isValidAppointmentInterval(startDate, endDate, cellDuration);
    }

    function isValidAppointmentInterval(startDate, endDate, cellDuration) {
        var edgeEndDate = new Date(endDate.getTime() - 1);

        if (!isValidAppointmentDate(edgeEndDate)) {
            return false;
        }

        var durationInMs = cellDuration * 60 * 1000;
        var date = startDate;
        while (date <= endDate) {
            if (!isValidAppointmentDate(date)) {
                return false;
            }
            var newDateTime = date.getTime() + durationInMs - 1;
            date.setTime(newDateTime);
        }

        return true;
    }

    function isValidAppointmentDate(date) {
        return !isHoliday(date) && !isDinner(date) && !isWeekend(date);
    }

    function isHoliday(date) {
        var localeDate = date.toLocaleDateString();
        return holidays.filter(function(holiday) {
            return holiday.toLocaleDateString() === localeDate;
        }).length > 0;
    }

    function isWeekend(date) {
        var day = date.getDay();
        return day === 0 || day === 6;
    }

    function isDinner(date) {
        var hours = date.getHours();
        return hours >= dinnerTime.from && hours < dinnerTime.to;
    }

    function applyDisableDatesToDateEditors(form) {
        var startDateEditor = form.getEditor('StartDate');
        startDateEditor.option('disabledDates', holidays);

        var endDateEditor = form.getEditor('EndDate');
        endDateEditor.option('disabledDates', holidays);
    }

</script>
